//7．编写一个与编程练习6功能相同的程序，
//使用unsigned long类型的变量储存字体信息，
//并且使用按位运算符而不是位成员来管理这些信息。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <assert.h>
#include <stdbool.h>
#include <mylib.h>

#define ID_POS 0
#define ID_MASK 0xFFL

#define SIZE_POS 8
//注意加()，宏定义会替换文本，而不是值
#define SIZE_MASK (0x7FL<<SIZE_POS)

#define ALIGNMENT_POS    15
#define ALIGNMENT_MASK   (0x3L<<ALIGNMENT_POS)
#define ALIGNMENT_LEFT   (0x0L<<ALIGNMENT_POS)
#define ALIGNMENT_CENTER (0x1L<<ALIGNMENT_POS)
#define ALIGNMENT_RIGHT  (0x2L<<ALIGNMENT_POS)

#define B_POS 17
#define B_MASK (1L<<B_POS)

#define I_POS 18
#define I_MASK (1L<<I_POS)

#define U_POS 19
#define U_MASK (1L<<U_POS)


static char choice_menu(unsigned long font);


//
int main(void) {
    unsigned long font = 0x1L | (0xCL << SIZE_POS);
    char sel;
    while ((sel = choice_menu(font)) != 'q') {
        switch (sel) {
            case 'f':
                printf("Enter font id(0-255):");
                unsigned long id = get_range_i(0L, 255L);
                //清除当前ID
                font &= ~ID_MASK;
                font |= id << ID_POS;
                break;
            case 's':
                printf("Enter font size(0-127):");
                unsigned long size = get_range_i(0L, 127L);
                //清除当前ID
                font &= ~SIZE_MASK;
                font |= size << SIZE_POS;
                break;
            case 'a':
                printf("Select alignment:\n"
                       "1)left\t2)center\t3)right\n");
//                printf("%#x\n",ALIGNMENT_MASK);
//                printf("%#x\n",~ALIGNMENT_MASK);
                font &= ~ALIGNMENT_MASK;
                switch (get_range_i(1, 3)) {
                    case 1:
                        font |= ALIGNMENT_LEFT;
                        break;
                    case 2:
                        font |= ALIGNMENT_CENTER;
                        break;
                    case 3:
                        font |= ALIGNMENT_RIGHT;
                        break;
                }
                break;
            case 'b':
                font ^= B_MASK;
                break;
            case 'i':
                font ^= I_MASK;
                break;
            case 'u':
                font ^= U_MASK;
                break;
        }
    }
    printf("Bye!");
    return 0;
}


static char choice_menu(unsigned long font) {
    //打印当前信息
    puts("ID\tSIZE\tALIGNMENT\tB\tI\tU");
    char align[7];
    switch (font & ALIGNMENT_MASK) {
        case ALIGNMENT_LEFT:
            strcpy(align, "left");
            break;
        case ALIGNMENT_CENTER:
            strcpy(align, "center");
            break;
        case ALIGNMENT_RIGHT:
            strcpy(align, "right");
            break;
    }
    printf("%ld\t%ld\t\t%s\t\t%s\t%s\t%s\n\n",
           (font & ID_MASK) >> ID_POS,
           (font & SIZE_MASK) >> SIZE_POS,
           align,
           font & B_MASK ? "on" : "off",
           font & I_MASK ? "on" : "off",
           font & U_MASK ? "on" : "off");

    //打印菜单
    puts("f)change font\ts)change size\ta)change alignment\t");
    puts("b)toggle bold\ti)toggle italic\tu)toggle underline\t");
    puts("q)quit");
    const int st_size = 10;
    char st[st_size];
    char chs[] = "f|s|a|b|i|u|q";
    while (s_gets(st, st_size) == NULL || strchr(chs, st[0]) == NULL) {
        printf("输入%s\n", chs);
    }
    return st[0];
}

